package com.sh.data.engine.domain.common.model.domain;

import gudusoft.gsqlparser.TCustomSqlStatement;
import gudusoft.gsqlparser.TGSqlParser;
import gudusoft.gsqlparser.dlineage.dataflow.listener.DataFlowHandleListener;

import java.io.File;
import java.text.SimpleDateFormat;
import java.util.Date;


public class DataFlowHandleTimeListener implements DataFlowHandleListener {

    private long startAnalyzeTime;

    private long startParseTime;

    private long startParseSQLEnvTime;

    private long startDataFlowTime;

    private long startStatementTime;

    private long totalScriptCount;

    private int totalStatementCount;

    private int parseIndex = 0;

    private int analyzeIndex = 0;

    private long startToXMLTime;

    private File file;

    public void startAnalyze(File file, long fileCountOrSqlLength, boolean isFileCount) {
        this.file = file;
        this.startAnalyzeTime = System.currentTimeMillis();
        String time = formatLogTime(this.startAnalyzeTime);
        if (file != null) {
            if (isFileCount) {
                this.totalScriptCount = fileCountOrSqlLength;
                String info =
                    time + "  Start analyzing directory " + file.getName() + ", the file count is "
                        + fileCountOrSqlLength + ".";
                System.out.println(info);
            } else {
                this.totalScriptCount = 1L;
                String info = time + "  Start analyzing file " + file.getName() + ", the file length is "
                    + fileCountOrSqlLength + ".";
                System.out.println(info);
            }
        } else if (isFileCount) {
            this.totalScriptCount = fileCountOrSqlLength;
            String info =
                time + "  Start analyzing SQL scripts, the scripts count is " + fileCountOrSqlLength
                    + ".";
            System.out.println(info);
        } else {
            this.totalScriptCount = 1L;
            String info =
                time + "  Start analyzing SQL script , the script lenght is " + fileCountOrSqlLength
                    + ".";
            System.out.println(info);
        }
        this.parseIndex = 0;
        this.analyzeIndex = 0;
    }

    public void startParse(File file, String sql) {
        this.startParseTime = System.currentTimeMillis();
        String time = formatLogTime(this.startParseTime);
        if (file != null) {
            String info = time + "  Start parsing the " + ((this.totalScriptCount == 1L) ? ""
                : (++this.parseIndex + "th/" + this.totalScriptCount)) + " file " + file.getName()
                + ", the file length is " + sql.length() + ".";
            System.out.println(info);
        } else {
            String info = time + "  Start parsing SQL script, the script length is " + sql.length() + ".";
            System.out.println(info);
        }
    }

    public void startParseSQLEnv() {
        this.startParseSQLEnvTime = System.currentTimeMillis();
        String time = formatLogTime(this.startParseSQLEnvTime);
        String info = time + "  Start parsing SQLEnv.";
        System.out.println(info);
    }

    public void endParseSQLEnv() {
        long currentTime = System.currentTimeMillis();
        String time = formatLogTime(currentTime);
        String info = time + "  Parse SQLEnv finished, spend time " + formatTime(
            currentTime - this.startParseSQLEnvTime) + ".";
        System.out.println(info);
    }

    public void endParse(boolean isSuccess) {
        long currentTime = System.currentTimeMillis();
        String time = formatLogTime(currentTime);
        String info = time + "  Parse SQL script finished, spend time " + formatTime(
            currentTime - this.startParseTime) + ".";
        System.out.println(info);
    }

    public void startAnalyzeDataFlow(TGSqlParser sqlparser) {
        this.totalStatementCount = sqlparser.getSqlstatements().size();
        this.startDataFlowTime = System.currentTimeMillis();
        String time = formatLogTime(this.startDataFlowTime);
        String info =
            time + "  Start analyzing data flow, the statements count is " + this.totalStatementCount
                + ".";
        System.out.println(info);
    }


    @Override
    public void startAnalyzeStatment(TCustomSqlStatement stmt) {
    }

    public void endAnalyzeStatment(TCustomSqlStatement stmt) {
    }

    public void endAnalyzeDataFlow(TGSqlParser sqlparser) {
        long currentTime = System.currentTimeMillis();
        String time = formatLogTime(currentTime);
        String info = time + "  Analyze data flow finished, spend time " + formatTime(
            currentTime - this.startDataFlowTime) + ".";
        System.out.println(info);
    }

    public void startOutputDataFlowXML() {
        this.startToXMLTime = System.currentTimeMillis();
        String time = formatLogTime(this.startToXMLTime);
        String info = time + "  Start output the data flow xml.";
        System.out.println(info);
    }

    public void endOutputDataFlowXML(long length) {
        long currentTime = System.currentTimeMillis();
        String time = formatLogTime(currentTime);
        String info =
            time + "  Output the data flow xml finished, length is " + length + ", spend time "
                + formatTime(currentTime - this.startToXMLTime) + ".";
        System.out.println(info);
    }

    public void endAnalyze() {
        long currentTime = System.currentTimeMillis();
        String time = formatLogTime(currentTime);
        String info = time + "  Execute the data flow analyse finished, spend time " + formatTime(
            currentTime - this.startAnalyzeTime) + ".";
        if (this.file != null) {
            info = info + "\nFile path: " + this.file.getAbsolutePath();
        }
        System.out.println(info);
    }

    public boolean isCanceled() {
        return false;
    }

    private String formatLogTime(long time) {
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        return df.format(new Date(time));
    }

    private String formatTime(long time) {
        if (time > 1000L) {
            return (time / 1000L) + " seconds";
        }
        return time + " ms";
    }
}